import { across, bet, tower } from '@prisma/client'
import { calcAngle, calcF, calcFB, calcHi, calcTAFromTB, calcTBFromFB } from 'src/section/utils/ljImageMath'
import CreateAcrossForceDecorator from '../decorator/CreateAcrossForceDecorator'

interface CalculateTTfonfig {
  btName: string
  h: number
  FB: number
  Hi: number
  angle: number
}

export class AcrossCalculate {
  constructor(
    private lst_tower: tower[],
    private lst_bet: bet[],
    private lst_across: across[],
    private w: number,
    private e: number,
  ) {}

  calculate() {
    const lst_across_force = []
    for (const across of this.lst_across) {
      const bet = this.lst_bet.find((b) => b.btName === across.btName)
      const [t1, t2] = across.btName.split('--')
      const tower1 = this.lst_tower.find((t) => t.tName === t1)
      const tower2 = this.lst_tower.find((t) => t.tName === t2)

      const n = across.acrossX
      const l = bet.btSpan
      const h = tower2.altitude - tower1.altitude
      const N = tower1.altitude
      const y = across.acrossY + across.controlHeight

      const angle = calcAngle(h, l)
      const Hi = calcHi(this.w, n, l, N, y, angle)
      const f = calcF(l, this.w, Hi, angle) // 最大弧垂
      const FB = calcFB(f, h)
      const TT = this.calculateTT({
        btName: across.btName,
        h,
        FB,
        Hi,
        angle,
      })

      lst_across_force.push({
        acrossId: across.id,
        h,
        angle,
        Hi,
        f,
        FB,
        TT,
      })
    }

    return lst_across_force
  }

  // 计算出口张力
  private calculateTT(config: CalculateTTfonfig) {
    const { btName, h, FB, Hi, angle } = config

    // 计算第index档内TB 和 TA
    const index = this.lst_bet.findIndex((bet) => bet.btName === btName)
    let TB = calcTBFromFB(Hi, this.w, FB, angle)
    let TA = calcTAFromTB(TB, this.w, h, angle)
    // 计算第index-1档内TB
    const TT = this.calcultateTA(TA, index - 1)
    return TT
  }

  // 采用递归的方式计算TA
  private calcultateTA(T: number, index: number) {
    if (index < 0) return T

    const TB = T / this.e
    const [tname1, tname2] = this.lst_bet[index].btName.split('--')
    const tower1 = this.lst_tower.find((t) => t.tName == tname1)
    const tower2 = this.lst_tower.find((t) => t.tName == tname2)
    const h = tower2.altitude - tower1.altitude

    const angle = calcAngle(h, this.lst_bet[index].btSpan)
    const TA = calcTAFromTB(TB, this.w, h, angle)

    return this.calcultateTA(TA, index - 1)
  }
}
